home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-11-15 | 14.7 KB | 508 lines | [TEXT/CWIE] |
- {This file was processed by Dan's Source Converter}
- {version 1.3 (this version modified by Ingemar Ragnemalm)}
-
-
- {09-15-96 Should be working now}
- {Matt Mora fixed some porting bugs}
- {mxmora@apple.com}
-
-
- unit Box3DSupport;
- interface
- uses
- Types, QuickDraw, Events, Windows, Dialogs, Fonts, DiskInit, TextEdit, Traps,{}
- Memory, SegLoad, Scrap, ToolUtils, OSUtils, Menus, Resources, StandardFile,{}
- GestaltEqu, Files, Errors, Devices, QuickDrawText, TextUtils, {}
- QDOffScreen,
-
- QD3D, QD3DDrawContext, QD3DRenderer, QD3DShader, QD3DCamera, QD3DLight, QD3DGeometry, QD3DGroup, QD3DMath, QD3DSet, QD3DTransform, QD3DAcceleration, QD3DView;
-
-
- function MyQD3DInitialize (): OSErr;
- function MyQD3DExit: OSErr;
-
- function MyNewView (theWindow: WindowPtr): TQ3ViewObject;
- function MyNewDrawContext (theWindow: WindowPtr): TQ3DrawContextObject;
- function MyNewCamera (theWindow: WindowPtr): TQ3CameraObject;
- function MyNewLights (): TQ3GroupObject;
- function MyNewModel (): TQ3GroupObject;
-
- function InputHelloWorldModel: TQ3GroupObject;
- function InputFactModel: TQ3GroupObject;
-
- function AdjustCamera (theView: TQ3ViewObject; mainGroup: TQ3GroupObject; winWidth: Integer; winHeight: Integer): TQ3Point3D;
-
- implementation
-
- { My3dSupport.c - QuickDraw 3d routines}
- {}
- { This file contains utility routines for QuickDraw 3d sample code.}
- { This is a simple QuickDraw 3d application to draw a cube in the center }
- { of the main application window. The routines in here handle setting up}
- { the main display group, the view, the Macintosh 3D draw context, and the}
- { camera and lighting. }
- {}
- { This code is the basis of the introductory article in d e v e l o p issue 22}
- {}
- { Nick Thompson - January 6th 1995}
- { }
- { ©1994-95 Apple computer Inc., All Rights Reserved}
-
-
- var
- documentGroupCenter: TQ3Point3D;
- documentGroupScale: Real;
-
-
- function MyNewView (theWindow: WindowPtr): TQ3ViewObject;
-
- var
- myStatus: TQ3Status;
- myView: TQ3ViewObject;
- myDrawContext: TQ3DrawContextObject;
- myRenderer: TQ3RendererObject;
- myCamera: TQ3CameraObject;
- myLights: TQ3GroupObject;
- label bail;
- begin
- myView := Q3View_New;
-
- { Create and set draw context.}
- myDrawContext := MyNewDrawContext(theWindow);
- if myDrawContext = nil then
- goto bail;
-
- myStatus := Q3View_SetDrawContext(myView, myDrawContext);
- if myStatus = kQ3Failure then
- goto bail;
-
- myStatus := Q3Object_Dispose(myDrawContext);
-
- { Create and set renderer.}
-
-
-
- { this would use the Z-Buffer renderer}
- if false then
- begin
-
- (* myRenderer := Q3Renderer_NewFromType(kQ3RendererTypeWireFrame);}
- { If ((myStatus := Q3View_SetRenderer(myView, myRenderer)) = kQ3Failure ) Then }
- { goto bail;}
- {*)
- end
- else
- begin
- { this would use the interactive software renderer}
-
- myRenderer := Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
- if myRenderer <> nil then
- begin
- myStatus := Q3View_SetRenderer(myView, myRenderer);
- if myStatus = kQ3Failure then
- goto bail;
- { these two lines set us up to use the best possible renderer,}
- { including hardware if it is installed.}
- myStatus := Q3InteractiveRenderer_SetDoubleBufferBypass(myRenderer, kQ3True);
- myStatus := Q3InteractiveRenderer_SetPreferences(myRenderer, kQAVendor_BestChoice, 0);
-
- end
- else
- goto bail;
- end;
-
- myStatus := Q3Object_Dispose(myRenderer);
-
- myCamera := MyNewCamera(theWindow);
- { Create and set camera.}
- if (myCamera = nil) then
- goto bail;
-
- myStatus := Q3View_SetCamera(myView, myCamera);
- if myStatus = kQ3Failure then
- goto bail;
-
- myStatus := Q3Object_Dispose(myCamera);
-
- { Create and set lights.}
- myLights := MyNewLights;
- if myLights = nil then
- goto bail;
-
- myStatus := Q3View_SetLightGroup(myView, myLights);
- if myStatus = kQ3Failure then
- goto bail;
-
- myStatus := Q3Object_Dispose(myLights);
-
- { Done!!!}
- MyNewView := myView;
- exit(MyNewView); {mxm}
- bail:
- { If any of the above failed, then don't return a view.}
- MyNewView := nil;
- end;
-
- {----------------------------------------------------------------------------------}
-
- function MyNewDrawContext (theWindow: WindowPtr): TQ3DrawContextObject;
-
- var
- myDrawContextData: TQ3DrawContextData;
- myMacDrawContextData: TQ3MacDrawContextData;
- ClearColor: TQ3ColorARGB;
- myDrawContext: TQ3DrawContextObject;
-
- { Set the background color.}
- begin
- ClearColor.a := 1.0;
- ClearColor.r := 1.0;
- ClearColor.g := 1.0;
- ClearColor.b := 1.0;
-
- { Fill in draw context data.}
- myDrawContextData.clearImageMethod := kQ3ClearMethodWithColor;
- myDrawContextData.clearImageColor := ClearColor;
- myDrawContextData.paneState := kQ3False;
- myDrawContextData.maskState := kQ3False;
- myDrawContextData.doubleBufferState := kQ3True;
-
- myMacDrawContextData.drawContextData := myDrawContextData;
-
- myMacDrawContextData.window := CGrafPtr(theWindow); { this is the window associated with the view}
- myMacDrawContextData.library := kQ3Mac2DLibraryNone;
- myMacDrawContextData.viewPort := nil;
- myMacDrawContextData.grafPort := nil;
-
- { Create draw context and return it, if it’s nil the caller must handle}
- myDrawContext := Q3MacDrawContext_New(myMacDrawContextData);
-
- MyNewDrawContext := myDrawContext;
- end;
-
-
- {----------------------------------------------------------------------------------}
- function MakePoint3D (x, y, z: Real): TQ3Point3D;
- {----------------------------------------------------------------------------------}
- begin
- MakePoint3D.x := x;
- MakePoint3D.y := y;
- MakePoint3D.z := z;
- end;
-
- {----------------------------------------------------------------------------------}
- function MakeVector3D (x, y, z: Real): TQ3Vector3D;
- {----------------------------------------------------------------------------------}
- begin
- MakeVector3D.x := x;
- MakeVector3D.y := y;
- MakeVector3D.z := z;
- end;
-
- {----------------------------------------------------------------------------------}
- function MakeColorRGB (r, g, b: Real): TQ3ColorRGB;
- {----------------------------------------------------------------------------------}
- begin
- MakeColorRGB.r := r;
- MakeColorRGB.g := g;
- MakeColorRGB.b := b;
- end;
-
- {----------------------------------------------------------------------------------}
- function MyNewCamera (theWindow: WindowPtr): TQ3CameraObject;
- {----------------------------------------------------------------------------------}
-
- var
- perspectiveData: TQ3ViewAngleAspectCameraData;
- camera: TQ3CameraObject;
-
- fieldOfView: Real;
- hither: Real;
- yon: Real;
- returnVal: TQ3Status;
-
- begin
- fieldOfView := 1.0;
- hither := 0.001;
- yon := 1000;
- returnVal := kQ3Failure;
-
- perspectiveData.cameraData.placement.cameraLocation := MakePoint3D(0.0, 0.0, 7.0); {from}
- perspectiveData.cameraData.placement.pointOfInterest := MakePoint3D(0.0, 0.0, 0.0); {to}
- perspectiveData.cameraData.placement.upVector := MakeVector3D(0.0, 1.0, 0.0); {up}
-
- perspectiveData.cameraData.range.hither := hither;
- perspectiveData.cameraData.range.yon := yon;
-
- perspectiveData.cameraData.viewPort.origin.x := -1.0;
- perspectiveData.cameraData.viewPort.origin.y := 1.0;
- perspectiveData.cameraData.viewPort.width := 2.0;
- perspectiveData.cameraData.viewPort.height := 2.0;
-
- perspectiveData.fov := fieldOfView;
- perspectiveData.aspectRatioXToY := (theWindow^.portRect.right - theWindow^.portRect.left) / (theWindow^.portRect.bottom - theWindow^.portRect.top);
-
- camera := Q3ViewAngleAspectCamera_New(perspectiveData);
-
- MyNewCamera := camera;
- end;
-
-
-
- {----------------------------------------------------------------------------------}
- function MyNewLights: TQ3GroupObject;
- {----------------------------------------------------------------------------------}
-
- var
- myGroupPosition: TQ3GroupPosition;
- myLightList: TQ3GroupObject;
- myLightData: TQ3LightData;
- myPointLightData: TQ3PointLightData;
- myDirectionalLightData: TQ3DirectionalLightData;
- myAmbientLight, myPointLight, myFillLight: TQ3LightObject;
- pointLocation: TQ3Point3D;
- fillDirection: TQ3Vector3D;
- WhiteLight: TQ3ColorRGB;
- myStatus: TQ3Status;
-
- { Set up light data for ambient light. This light data will be used for point and fill}
- { light also.}
- label bail;
- begin
- pointLocation := MakePoint3D(-10.0, 0.0, 10.0);
- fillDirection := MakeVector3D(10.0, 0.0, 10.0);
- WhiteLight := MakeColorRGB(1.0, 1.0, 1.0);
-
-
- myLightData.isOn := kQ3True;
- myLightData.color := WhiteLight;
-
- { Create ambient light.}
- myLightData.brightness := 0.2;
- myAmbientLight := Q3AmbientLight_New(myLightData);
- if (myAmbientLight = nil) then
- goto bail;
-
- { Create point light.}
- myLightData.brightness := 1.0;
- myPointLightData.lightData := myLightData;
- myPointLightData.castsShadows := kQ3False;
- myPointLightData.attenuation := kQ3AttenuationTypeNone;
- myPointLightData.location := pointLocation;
- myPointLight := Q3PointLight_New(myPointLightData);
- if (myPointLight = nil) then
- goto bail;
-
- { Create fill light.}
- myLightData.brightness := 0.2;
- myDirectionalLightData.lightData := myLightData;
- myDirectionalLightData.castsShadows := kQ3False;
- myDirectionalLightData.direction := fillDirection;
- myFillLight := Q3DirectionalLight_New(myDirectionalLightData);
- if (myFillLight = nil) then
- goto bail;
-
- { Create light group and add each of the lights into the group.}
- myLightList := Q3LightGroup_New;
- if (myLightList = nil) then
- goto bail;
- myGroupPosition := Q3Group_AddObject(myLightList, myAmbientLight);
- if (myGroupPosition = nil) then
- goto bail;
- myGroupPosition := Q3Group_AddObject(myLightList, myPointLight);
- if (myGroupPosition = nil) then
- goto bail;
- myGroupPosition := Q3Group_AddObject(myLightList, myFillLight);
- if (myGroupPosition = nil) then
- goto bail;
-
- myStatus := Q3Object_Dispose(myAmbientLight);
- myStatus := Q3Object_Dispose(myPointLight);
- myStatus := Q3Object_Dispose(myFillLight);
-
- { Done!}
- MyNewLights := myLightList;
- exit(MyNewLights); {mxm}
-
- bail:
- { If any of the above failed, then return nothing!}
- MyNewLights := nil;
- end;
-
- (*
- { now longer needed since TQ3AttributeSetArrayPtr is now used in TQ3BoxData }
- type
- PtrArr = packed array[0..0] of Ptr; {This *might* match the faceAttributeSet!}
- PtrArrPtr = ^PtrArr;
- *)
-
-
- {----------------------------------------------------------------------------------}
- procedure MyColorBoxFaces (var myBoxData: TQ3BoxData);
- {----------------------------------------------------------------------------------}
-
- var
- faceColor: TQ3ColorRGB;
- face: Integer;
- myStatus: TQ3Status;
-
- { sanity check - you need to have set up }
- { the face attribute set for the box data }
- { before calling this.}
-
- begin
- if (myBoxData.faceAttributeSet = nil) then
- Exit(MyColorBoxFaces);
-
- { make each face of a box a different color}
-
- for face := 0 to 5 do
- begin
- myBoxData.faceAttributeSet^[face] := Q3AttributeSet_New;
- case face of
- 0:
- begin
- faceColor.r := 1.0;
- faceColor.g := 0.0;
- faceColor.b := 0.0;
- end;
- 1:
- begin
- faceColor.r := 0.0;
- faceColor.g := 1.0;
- faceColor.b := 0.0;
- end;
-
- 2:
- begin
- faceColor.r := 0.0;
- faceColor.g := 0.0;
- faceColor.b := 1.0;
- end;
-
- 3:
- begin
- faceColor.r := 1.0;
- faceColor.g := 1.0;
- faceColor.b := 0.0;
- end;
-
- 4:
- begin
- faceColor.r := 1.0;
- faceColor.g := 0.0;
- faceColor.b := 1.0;
- end;
-
- 5:
- begin
- faceColor.r := 0.0;
- faceColor.g := 1.0;
- faceColor.b := 1.0;
- end;
- end;
- myStatus := Q3AttributeSet_Add(myBoxData.faceAttributeSet^[face], kQ3AttributeTypeDiffuseColor, @faceColor);
- end;
- end;
-
- {----------------------------------------------------------------------------------}
- function MyAddTransformedObjectToGroup (theGroup: TQ3GroupObject; theObject: TQ3Object; var translation: TQ3Vector3D): TQ3GroupPosition;
- {----------------------------------------------------------------------------------}
-
- var
- transform: TQ3TransformObject;
- myStatus: TQ3Status;
- myGroupPosition: TQ3GroupPosition;
- begin
- transform := Q3TranslateTransform_New(translation);
- myGroupPosition := Q3Group_AddObject(theGroup, transform);
- myStatus := Q3Object_Dispose(transform);
- MyAddTransformedObjectToGroup := Q3Group_AddObject(theGroup, theObject);
- end;
-
-
- {----------------------------------------------------------------------------------}
- function MyNewModel: TQ3GroupObject;
- {----------------------------------------------------------------------------------}
- var
- myGroup: TQ3GroupObject;
- myBox: TQ3GeometryObject;
- myBoxData: TQ3BoxData;
- myGroupPosition: TQ3GroupPosition;
- myIlluminationShader: TQ3ShaderObject;
- translation: TQ3Vector3D;
-
- faces: array[0..5] of TQ3SetObject;
- face: Integer;
- myPoint3DPtr: TQ3Point3DPtr;
- myVector3DPtr: TQ3Vector3DPtr;
- myStatus: TQ3Status;
-
- { Create a group for the complete model.}
- { do not use Q3OrderedDisplayGroup_New since in this}
- { type of group all of the translations are applied before}
- { the objects in the group are drawn, in this instance we }
- { dont want this.}
- begin
- myGroup := Q3DisplayGroup_New;
- if myGroup <> nil then
-
- { Define a shading type for the group}
- { and add the shader to the group}
- begin
- myIlluminationShader := Q3PhongIllumination_New;
- myGroupPosition := Q3Group_AddObject(myGroup, myIlluminationShader);
-
- { set up the colored faces for the box data}
- myBoxData.faceAttributeSet := @faces;
- myBoxData.boxAttributeSet := nil;
- MyColorBoxFaces(myBoxData);
-
- { create the box itself}
- myPoint3DPtr := Q3Point3D_Set(myBoxData.origin, 0, 0, 0);
- myVector3DPtr := Q3Vector3D_Set(myBoxData.orientation, 0, 1, 0);
- myVector3DPtr := Q3Vector3D_Set(myBoxData.majorAxis, 0, 0, 1);
- myVector3DPtr := Q3Vector3D_Set(myBoxData.minorAxis, 1, 0, 0);
- myBox := Q3Box_New(myBoxData);
-
- { put four copies of the box into the group, each one with its own translation}
- translation.x := 0;
- translation.y := 0;
- translation.z := 0;
- myGroupPosition := MyAddTransformedObjectToGroup(myGroup, myBox, translation);
-
- translation.x := 2;
- translation.y := 0;
- translation.z := 0;
- myGroupPosition := MyAddTransformedObjectToGroup(myGroup, myBox, translation);
-
- translation.x := 0;
- translation.y := 0;
- translation.z := -2;
- myGroupPosition := MyAddTransformedObjectToGroup(myGroup, myBox, translation);
-
- translation.x := -2;
- translation.y := 0;
- translation.z := 0;
- myGroupPosition := MyAddTransformedObjectToGroup(myGroup, myBox, translation);
- end;
-
- { dispose of the objects we created here}
- if (myIlluminationShader <> nil) then
- myStatus := Q3Object_Dispose(myIlluminationShader);
-
- for face := 0 to 5 do
- begin
- if myBoxData.faceAttributeSet^[face] <> nil then
- myStatus := Q3Object_Dispose(myBoxData.faceAttributeSet^[face]);
- end;
-
- if myBox <> nil then
- myStatus := Q3Object_Dispose(myBox);
-
- { Done!}
- MyNewModel := myGroup;
- end;
-
- end.
-